package com.akcome.apollo.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.common.utils.bean.AkResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.akcome.apollo.common.AkResultHelper;
import com.akcome.apollo.common.ApolloConstants;
import com.akcome.apollo.common.TokenHelper;
import com.akcome.apollo.config.AliyunSmsService;
import com.akcome.apollo.domain.BmpSmsInfo;
import com.akcome.apollo.domain.DictionaryItem;
import com.akcome.apollo.domain.enums.SmsBusinessTypeEnum;
import com.akcome.apollo.domain.enums.SmsStatusEnum;
import com.akcome.apollo.domain.enums.YesOrNoEnum;
import com.akcome.apollo.domain.resultcode.CommonResultCode;
import com.akcome.apollo.domain.resultcode.UserResultCode;
import com.akcome.apollo.repository.BmpSmsInfoRepository;
import com.akcome.apollo.service.DictionaryItemService;
import com.akcome.apollo.service.SmsService;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;

@Service
public class SmsServiceImpl implements SmsService{
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private TokenHelper tokenHelper;
	
	//默认验证码
	@Value("${sms.code}")
	private String SMS_CODE;
	
	//短信验证码有效期
	@Value("${sms.max-age}")
	private int MAX_AGE;
	
	@Autowired
	private AliyunSmsService aliyunSmsService;
	
	@Autowired
	private BmpSmsInfoRepository bmpSmsInfoRepository;
	
	@Autowired
	private AkResultHelper akResultHelper;
	
	@Autowired
	private DictionaryItemService dictionaryItemService;

	@Override
	public AkResult sendSms(Long userId,String callCode,String mobile,String ip, String source, String businessType,HttpServletRequest request,HttpServletResponse response){
		//短信开关
		DictionaryItem dictionaryItem = dictionaryItemService.findConfig("SMS_SWITCH");
		String smsSwitch = dictionaryItem.getValue();
		String smsCode = SMS_CODE;
		if(YesOrNoEnum.YES.getCode().equals(smsSwitch)){
			smsCode = String.valueOf(RandomUtils.nextInt(100000, 999999));
		}
		logger.info("发送短信，mobile：{},code:{}",callCode+"-"+mobile,smsCode);
		AkResult result = sendSmsCaptcha(userId, callCode, mobile, ip, source, businessType, smsCode,smsSwitch);
		if(CommonResultCode.SUCCESS.getStatusCode().equals(result.getCode())){
			
			//保存短信验证码cookie
			Map<String, Object> claims = new HashMap<String, Object>();
			claims.put(ApolloConstants.PARAM_CALL_CODE, callCode);
			claims.put(ApolloConstants.PARAM_MOBILE, mobile);
			claims.put(ApolloConstants.PARAM_SMS_CODE, smsCode);
			String token = tokenHelper.generateToken(claims);
			Cookie cookie = new Cookie(ApolloConstants.COOKIE_SMS_CODE, token);
			cookie.setMaxAge(MAX_AGE);
			cookie.setPath("/");
			response.addCookie(cookie);
			
			//删除图片验证码cookie
			Cookie[] cookies = request.getCookies();
			if(null!=cookies){
				for (Cookie c : cookies) {
					if(ApolloConstants.COOKIE_IMAGE_CODE.equals(c.getName())){
						c.setValue(null);
	            		c.setMaxAge(0);
	            		c.setPath("/");
	            		response.addCookie(c);
					}
				}
			}
		}
		return result;
	}
	
	@Override
    public AkResult sendSmsCaptcha(Long userId, String callCode, String mobile, String ip, String source, String businessType, String captcha,String smsSwitch){
        try {
			BmpSmsInfo smsInfo = new BmpSmsInfo();
			smsInfo.setBusinessType(businessType);
			smsInfo.setUserId(userId);
			smsInfo.setCallCode(callCode);
			smsInfo.setMobile(mobile);
			smsInfo.setCreateTime(new Date());
			smsInfo.setIp(ip);
			smsInfo.setSource(source);

			Map<String, Object> param = new HashMap<>();
			param.put("code", captcha);

			if(YesOrNoEnum.YES.getCode().equals(smsSwitch)){
				this.sendSms(mobile, businessType, smsInfo, param);
			}else{
				smsInfo.setErrorCode("OK");
			}
			bmpSmsInfoRepository.save(smsInfo);

			if(smsInfo.getErrorCode().equals("OK")) {
				return akResultHelper.buildSuccessAkResult(null);
			} else if(smsInfo.getErrorCode().equals("isv.BUSINESS_LIMIT_CONTROL")){
				//短信发送频繁
				return akResultHelper.buildFailAkResult(UserResultCode.BUSINESS_LIMIT_CONTROL);
			} else {
				return akResultHelper.buildFailAkResult(CommonResultCode.SYSTEM_ERROR);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return akResultHelper.buildFailAkResult(CommonResultCode.SYSTEM_ERROR);
		}
    }

    private void sendSms(String mobile, String businessType, BmpSmsInfo smsInfo, Map<String, Object> param) throws ClientException {
        SendSmsResponse sendSmsResponse = aliyunSmsService.sendSms(mobile, SmsBusinessTypeEnum.getByCode(businessType), param);
        if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
        	
            QuerySendDetailsResponse querySendDetailsResponse = aliyunSmsService.querySms(mobile, sendSmsResponse.getBizId(), DateFormatUtils.format(smsInfo.getCreateTime(), "yyyyMMdd"));
            // 获取返回结果
            if(querySendDetailsResponse.getCode() != null && querySendDetailsResponse.getCode().equals("OK")){
                //代表请求成功
                List<QuerySendDetailsResponse.SmsSendDetailDTO> list = querySendDetailsResponse.getSmsSendDetailDTOs();
                if(list != null && list.size() > 0) {
                    QuerySendDetailsResponse.SmsSendDetailDTO smsSendDetail = list.get(0);
                    String msg = smsSendDetail.getContent();
                    smsInfo.setMsg(msg);
                }
            }
            smsInfo.setStatus(SmsStatusEnum.SUCCESS.getCode());
        } else {
            logger.error("短信发送错误：errorCode:{}, errorMessage:{}", sendSmsResponse.getCode(), sendSmsResponse.getMessage());
            smsInfo.setStatus(SmsStatusEnum.FAIL.getCode());
        }
        smsInfo.setErrorCode(sendSmsResponse.getCode());
        smsInfo.setErrorMsg(sendSmsResponse.getMessage());
    }
}
